package com.cy.aspect;

import com.cy.common.annotation.RequiredPermissions;
import com.cy.common.exception.ServiceException;
import com.cy.common.untils.ServletUtil;
import com.cy.dao.SysMenuDao;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpSession;
import java.lang.reflect.Method;
import java.util.Set;

@Slf4j
@Aspect
@Component
public class PermissionAspect {
    @Autowired
    private SysMenuDao sysMenuDao;

    @Pointcut("@annotation(com.cy.common.annotation.RequiredPermissions)")
    public void doPermission(){};

    @Around("doPermission()")
    public Object doAround(ProceedingJoinPoint jp)throws Throwable{
        try {
            //执行目标方法(切点方法中的某个方法)
            Object result = doSelectPermission(jp);
            return result;//目标业务方法的执行结果
        }catch(Throwable e){
            e.printStackTrace();
            throw e;
        }
    }

    public Object doSelectPermission(ProceedingJoinPoint jp) throws Throwable{
        //1.获取注解上的权限 sys:user:select
        //1.3.1 获取目标对象类型
        Class<?> targetCls=jp.getTarget().getClass();
        //1.3.2 获取目标方法
        MethodSignature ms=
                (MethodSignature) jp.getSignature();//方法签名
        Method targetMethod=targetCls.getMethod(
                ms.getName(),ms.getParameterTypes());
        //1.3.3 获取方法上 RequiredLog 注解
        RequiredPermissions annotation =
                targetMethod.getAnnotation(RequiredPermissions.class);
        //1.3.4 获取注解中定义操作名
        String operation=annotation.value();
        log.info("权限是 {}",operation);
        //2.获取session对象上的userId
        HttpSession session = ServletUtil.getSession();
        Integer userId = (Integer) session.getAttribute("userId");
        //3.查询该用户的所有权限
        Set<String> stringSet = sysMenuDao.selectUserPermissions(userId);
        stringSet.stream().forEach(e->{
            log.info("qqqqqq is {}",e);
        });
        //4.查看是否有权限
        if(stringSet.contains(operation)){
            Object proceed = jp.proceed();
            return proceed;
        }else {
            throw new ServiceException("没有权限");
        }

    }
}
